﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;

public class LogHelpter
{
    /// <summary>
    /// 是否保存日志，true保存，false不保存。
    /// </summary>
    public static bool IS_SAVE_LOG = true;

    /// <summary>
    /// 最多记录30个日志文件，其他的删除历史文件
    /// </summary>
    const int MAX_FILE_COUNT = 30;

    /// <summary>
    /// 文件保存的目录
    /// </summary>
    static string fileSaveDir = "";

    /// <summary>
    /// 限制文件生成大小，1024000字节,大约1024kb，1M
    /// </summary>
    const long fileBytes = 1024000;

    //日志文件保存根路径   
    const string saveFolder = "DXLogs";

    private readonly static object lockObj = new object();

    static LogHelpter()
    {
        // 使用 Thread 替代 Task
        Thread deleteThread = new Thread(DeleteOldLogs);
        deleteThread.IsBackground = true; // 设置为后台线程
        deleteThread.Start();
    }

    /// <summary>
    /// 删除旧日志文件
    /// </summary>
    private static void DeleteOldLogs()
    {
        while (true)
        {
            try
            {
                // 自动删除文件
                string[] filePathArr = Directory.GetFileSystemEntries(fileSaveDir);

                if (filePathArr == null || filePathArr.Length == 0)
                {
                    goto DO_SLEEP;
                }

                List<FileInfo> files = new List<FileInfo>();
                foreach (string item in filePathArr)
                {
                    FileInfo fileInfo = new FileInfo(item);
                    files.Add(fileInfo);
                }

                // 按最后修改时间排序
                files.Sort(delegate(FileInfo x, FileInfo y) { return y.LastWriteTime.CompareTo(x.LastWriteTime); });

                // 删除超过 MAX_FILE_COUNT 的文件
                if (files.Count > MAX_FILE_COUNT)
                {
                    for (int i = MAX_FILE_COUNT; i < files.Count; i++)
                    {
                        files[i].Delete();
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("LogHelpter执行删除文件功能异常: " + ex.Message);
            }

        DO_SLEEP:
            Thread.Sleep(60000); // 休眠 60 秒
        }
    }

    /// <summary>
    /// 获取新的日志文件名
    /// </summary>
    /// <param name="fileFolderPath">文件保存目录</param>
    /// <param name="fileNameNoExtension">文件名（不含扩展名）</param>
    /// <param name="fileNamePrefix">文件名前缀</param>
    /// <returns></returns>
    static string GetNewFileName(string fileFolderPath, string fileNameNoExtension, string fileNamePrefix)
    {
        string fileName = string.Empty;

        // 文件名前缀
        fileNamePrefix = string.IsNullOrEmpty(fileNamePrefix) ? "" : fileNamePrefix;
        int index = 1;

        if (fileNameNoExtension.LastIndexOf('_') == -1)
        {
            // 默认文件名
            fileName = Path.Combine(fileFolderPath, fileNamePrefix + DateTime.Now.ToString("yyyy-MM-dd") + "_" + index + ".log");
        }
        else
        {
            string[] arr = fileNameNoExtension.Split('_');
            int.TryParse(arr[arr.Length - 1], out index);
            if (index == 0 || index > 900)
            {
                index = 1;
            }
        }

        fileName = Path.Combine(fileFolderPath, fileNamePrefix + DateTime.Now.ToString("yyyy-MM-dd") + "_" + index + ".log");

        while (File.Exists(fileName))
        {
            if (new FileInfo(fileName).Length < fileBytes)
            {
                break;
            }
            index++;
            fileName = Path.Combine(fileFolderPath, fileNamePrefix + DateTime.Now.ToString("yyyy-MM-dd") + "_" + index + ".log");
        }

        return fileName;
    }

    /// <summary>  
    /// 日志记录，在程序执行的根目录，写入txt文件，文件固定大小，超过限定大小自动创建新日志文件
    /// </summary>  
    /// <param name="msg">记录内容</param>  
    /// <param name="storeDir">文件保存文件夹</param>  
    /// <param name="fileNamePrefix">文件名前缀_</param>  
    public static void AddLog(string msg, string storeDir, string fileNamePrefix)
    {
        if (IS_SAVE_LOG)  // 如果保存开关开启，则保存日志
        {
            lock (lockObj)
            {
                try
                {
                    // 文件名前缀
                    fileNamePrefix = string.IsNullOrEmpty(fileNamePrefix) ? "" : fileNamePrefix + "_";

                    string fileFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, saveFolder);

                    if (!string.IsNullOrEmpty(storeDir))
                    {
                        fileFolderPath = Path.Combine(fileFolderPath, storeDir);
                    }

                    if (!Directory.Exists(fileFolderPath))
                    {
                        Directory.CreateDirectory(fileFolderPath);
                    }

                    fileSaveDir = fileFolderPath;
                    string fileName = string.Empty;

                    string[] files = Directory.GetFiles(fileFolderPath);
                    if (files.Length == 0)
                    {
                        fileName = Path.Combine(fileFolderPath, fileNamePrefix + DateTime.Now.ToString("yyyy-MM-dd") + "_1.log");
                        goto DO_WRITE;
                    }

                    // 按文件名中的数字排序
                    List<string> fileList = new List<string>(files);
                    fileList.Sort(delegate(string x, string y)
                    {
                        int xIndex = int.Parse(Path.GetFileNameWithoutExtension(x).Split('_')[1]);
                        int yIndex = int.Parse(Path.GetFileNameWithoutExtension(y).Split('_')[1]);
                        return yIndex.CompareTo(xIndex);
                    });

                    FileInfo fileInfo = new FileInfo(fileList[0]);
                    string fileNameNoExtension = Path.GetFileNameWithoutExtension(fileInfo.Name);
                    fileName = GetNewFileName(fileFolderPath, fileNameNoExtension, fileNamePrefix);

                DO_WRITE:
                    using (FileStream fs = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.Write))
                    {
                        string msg2 = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + ">>" + msg + Environment.NewLine;
                        byte[] logBytes = Encoding.UTF8.GetBytes(msg2);
                        fs.Write(logBytes, 0, logBytes.Length);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("LogHelpter日志写入异常：" + ex.ToString());
                }
            }
        }
    }
}